<template>
    <div class="bi-tree-item">
        <div class="tree-label" :class="[haveChildren?'have-children':'',last?'last':position,currentDisabled?'disabled':'']" @click="handelTitleClick" >
            <div class="tree-line" v-for="l in level" :class="l" ></div>
            <div class="tree-dot" :class="[fold?'fold':'unfold']" @click.stop="handleFold" ></div>
            <div class="tree-checkbox" :class="[check?'checked':'',halfCheck?'half-check':'']" v-if="checkbox" @click.stop="handleCheck" >
                <div class="input"></div>
            </div>
            <bi-icon :data="item.icon" v-if="item.icon"  ></bi-icon>
            <div class="title">{{item[titleKey]}}</div>
        </div>
        <div class="children"  :style="{display:fold?'none':'block'}"  v-if="haveChildren && change ">
            <tree-item 
                v-for="(item,index) in children" 
                :item="item" :key="item.__id"  
                :position="itemPosition(index)" 
                :last="itemLast(index)"
                :level="itemLevel(index)" >
            </tree-item>
        </div>
    </div>
</template>

<script>
export  default{
    inject:['itemKey','titleKey','titleClick','childrenClick','checkbox','type','updateCheck','updateFold','disabledNode'],
    name:'tree-item',
    data(){

        let haveChildren = this.item.children && this.item.children.length>0;
        let children = [];
        if (haveChildren){
            children = this.item.children;
        }

        let key = this.item[this.itemKey];

        if (key &&  typeof key.toString === "function") {
            key = key.toString();
        }

        return {
            key,   
            check:this.item.check,
            halfCheck:this.item.halfCheck,
            fold:this.item.fold,
            haveChildren,
            change:true,
            children
        }
    },
    computed:{
        currentDisabled(){
            if (this.disabled) return true;
            if (this.item.disabled) return true;
            if (this.disabledNode.includes(this.key)){
                return true;
            }

            return false;
        }
    },
    props:{
        item:{
            type:Object,
        },
        position:{
            type:String
        },
        last:{
            type:Boolean,
            default:false
        },
        level:{
            type:Array,
            default:[]
        },
        disabled:{
            type:Boolean,
            default:false
        }
    },
    methods:{
        handelTitleClick($event){
            
            if (this.currentDisabled){
                $event.stopPropagation();
                return;
            }

            if (this.childrenClick && this.haveChildren){
                $event.stopPropagation();
                return;
            }

            this.titleClick(this.item);
        },
        handleCheck(){

            if (this.currentDisabled){
                return;
            }
            this.change = false;
            let check = !this.check;

            if (this.halfCheck){
                this.halfCheck = false;
                this.check = true;
            } 
            else{
                this.check = !this.check;
            }


            let checkAndHalfCheck =  (childrens) =>{
                let checkCount = 0;
                let halfCheckCount = 0;
                let _check = false;
                let _halfCheck = false;
                for(let i in childrens){
                    if (childrens[i].check) checkCount++;
                    if (childrens[i].halfCheck) halfCheckCount++;
                }

                if (checkCount === childrens.length){
                    _check = true;
                    _halfCheck = false;
                }

                if (checkCount > 0 && checkCount < childrens.length || halfCheckCount > 0){
                    _halfCheck = true;
                    _check = false;
                }

                if (checkCount ==0 && halfCheckCount ==0){
                    _check = false;
                    _halfCheck = false;
                }

                return {check:_check,halfCheck:_halfCheck}
            }



            let setChilrenCheck =  (childrens,check) =>{
                for(let i in childrens){

                    if (childrens[i].disabled) continue;
                    
                    if (childrens[i].children){
                        childrens[i].children = setChilrenCheck(childrens[i].children,check);
                        let checkValue = checkAndHalfCheck(childrens[i].children);
                        childrens[i].check = checkValue.check;
                        childrens[i].halfCheck = checkValue.halfCheck;                        
                    }else{
                        childrens[i].check = check;
                        childrens[i].halfCheck = false;
                    }

                    this.updateCheck(childrens[i][this.itemKey],childrens[i].check);
                }

                return childrens;
            }

            if (this.haveChildren){
                this.children  = setChilrenCheck(this.children,check);
                
                let checkValue = checkAndHalfCheck(this.children);

                this.check = checkValue.check;
                this.halfCheck = checkValue.halfCheck;
                
            }else{
                this.click =  check;
                this.halfCheck = false;
            }

          this.$nextTick(()=>{
               this.change = true;
               this.$parent.childrenPostCheck(this.item.__id,this.check,this.halfCheck);
           })
           
           this.updateCheck(this.item[this.itemKey],this.check);
        },
        handleFold(){

            this.fold = !this.fold;
            this.updateFold(this.item[this.itemKey],this.fold);
        },
        itemPosition(index){
            if (index == 0) return 'frist';
            else if (index == this.item.children.length-1) return 'last';
            else return 'middle';
        },
        itemLevel(index){
            let level = JSON.parse(JSON.stringify(this.level)); ;
            if (this.last)  level.push('last');
            else  level.push('');
            return level;
        },
        itemLast(index){
            return index == this.item.children.length-1;
        },
        childrenPostCheck(id,check,halfCheck){
            
            for (let i in this.children){
                if (this.children[i].__id == id){
                    this.children[i].check = check;
                    this.children[i].halfCheck = halfCheck;
                }
            }

            let halfCheckLength = 0;
            let checkLength  = 0;

            if (this.children.length>0){
                for (let i in this.children){
                    if (this.children[i].check){
                        checkLength ++;
                    }

                    
                    if (this.children[i].halfCheck){
                        halfCheckLength ++ ;
                    }
                }
            }
            
            if (checkLength == this.children.length){
                this.check = true;
                this.halfCheck = false;
            }else if (checkLength > 0 && checkLength < this.children.length){
                this.check = false;
                this.halfCheck = true;
            }else if (checkLength == 0 && halfCheckLength>0){
                this.check = false;
                this.halfCheck = true;
            }else{
                this.check = false;
                this.halfCheck = false;
            }

            this.updateCheck(this.item[this.itemKey],this.check);
            this.$parent.childrenPostCheck(this.item.__id,this.check,this.halfCheck);
        },
    }
    
}
</script>

<style>
.bi-tree .tree-label{
    display: flex;
    align-items: center;
}
.bi-tree  .tree-label.disabled{
    color: var(--bs-disabled-color);
}
.bi-tree .tree-label .title{
    font-size: 14px;
    user-select: none;
}
.bi-tree.default .tree-label .tree-dot{
    background-image: url();
    background-repeat: no-repeat;
    background-size: 148px 148px;
    width: 24px;
    height: 24px;
    cursor: pointer;
}

.bi-tree.default .tree-label .tree-dot{
    background-position-y: -35px;
    background-position-x: -10px;
    
}


.bi-tree.default .tree-label.last .tree-dot{
    background-position-y: -59px;
}

.bi-tree.default  .tree-label.have-children .tree-dot.fold{
    background-position-x: -57px;
}

.bi-tree.default  .tree-label.have-children .tree-dot.unfold{
    background-position-x: -99px;
}


.bi-tree.default  .tree-line{
    background-image: url();
    background-repeat: repeat-y;
    background-position: -2px 0px;
    background-size: 24px 24px;
    width: 24px;
    height: 24px;
}

.bi-tree.default  .tree-label .tree-line.last{
    background-image: none;
}





.bi-tree .tree-label .tree-checkbox{
    width: 18px;
    height: 24px;
    display: flex;
    justify-content:center;
    align-items: center;
    font-size: 0px;
    line-height: 0;
   
}

.bi-tree .tree-label .tree-checkbox .input{
    width: 14px;
    height:14px;
     cursor: pointer;
    border: 1px solid #666;
    border-radius: 2px;
    position: relative;
}

.bi-tree  .tree-label .tree-checkbox.disabled  .input{
    border: 1px solid #DDD;
    background-color: #F5F5F5;
    color:#ACA899;
}



.bi-tree  .tree-label .tree-checkbox.half-check .input:before{
    position: absolute;
    content: '';
    top: 2px;
    left: 2px;
    width: 8px;
    height: 7.5px;
    border-radius:1px;
    background-color: #333;
}

.bi-tree  .tree-label .tree-checkbox.disabled.half-check  .input:before{
    background-color: #ACA899;
}



.bi-tree  .tree-label .tree-checkbox.checked .input:before{
    position: absolute;
    content: '';
    top: 1px;
    left: 3.5px;
    width: 5px;
    height: 8px;
    border-bottom:2px solid  #333;
    border-right: 2px solid  #333;
    transform: rotate(45deg);
}


.bi-tree  .tree-label .tree-checkbox.disabled.checked  .input:before{
    border-bottom:2px solid  #ACA899;
    border-right: 2px solid  #ACA899;
}

.bi-tree.menu  .tree-line{
    width: 16px;
    height: 16px;
} 

.bi-tree.menu .tree-label:hover{
    background-color:rgba(90, 90, 90, 0.1);
}

.bi-tree.menu  .tree-label.disabled:hover{
    background-color: transparent;
}
.bi-tree.menu  .tree-label{
    padding: 10px;
}

.bi-tree.menu  .tree-label .tree-dot{
    width: 8px;
    height: 16px;
}

.bi-tree.menu  .tree-label.have-children .tree-dot{
    width: 16px;
    height: 16px;
    position: relative;
    cursor: pointer;
}
.bi-tree.menu  .tree-label.have-children .tree-dot::before{
    content: '';
    position: absolute;
    width: 8px;
    height: 8px;
    right: 8px;
    top: 50%;
    margin-top: -5px;
    z-index: 1;
    transform:rotate(-135deg);
    border-left: 1px solid #73787e;
    border-bottom: 1px solid #73787e;
}

.bi-tree.menu  .tree-label.have-children .tree-dot.unfold:before{
    transform:rotate(-45deg);
    margin-top: -6px;
}

</style>